<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/4/8 0008
 * Time: 19:24
 */
//条形图
$size_x = 640;
$size_y = 480;
$title = 'People m 0 ing to the snow every winter';
$title2 = 'Head count (in 1.000)';

$values = array(
    1999 => 5300,
    2000 => 5700,
    2001 => 6400,
    2002 => 6700,
    2003 => 6600,
    2004 => 7100
);
$max_value = 8000;
$units = 500;
//Values数组定义了我们将据此在图表中绘制柱形的数据集。通常来说，你不需要辛苦地把 这些值输入脚本中。实际上，这些值将由其他的资源获取，例如数据库。
//$max_value变量定义 的是图表中的最大值并且用来自动标定这些数值。$units变量定义了两个竖形的格子之间的距 离。

$img = imagecreatetruecolor($size_x, $size_y);
//增加一些随机的变形处理
imageantialias($img, true);
imagealphablending($img, true);
//与先前一样,我们创建一个真彩色的图片并且打开反锯齿处理。调用imagealphablending() 并不总是需要，因为真彩色图片中的这个设置总是true。Alpha混合是一
//个通过使用它的alpha 通道“混合”新绘制到图片的像素的技术。这里我们需要用到这个函数，因为我们想让图表中 的柱形透明些(让我们通过图片查看背景)。
//透明度是PHP的一种颜色属性，在脚本接下来使用 的imagecolorallocatealpha ()的第5个参数中定义。
$bg_image = './bg.png';
$bg = imagecreatefrompng($bg_image);
$size = getimagesize($bg_image);
//var_dump($size);
//脚本中刚才的部分通过imagecreatefrompng ()加载图片的背景。你还可以使用类似的函
//数读取 JPEG 文件(imagecreatef rorojpg {))和 GIF 文件(imagecreatefrorogif ())。 getimagesizeU函数返回包含一个图片的宽度与高度的数组，
//    还有一些附加信息。宽度与高度 是数组中的前两个元素。第3个兀素是字符串，widths ' 640 ' height= ' 480 ',你可以在需要的 时候把它嵌入到HTML当
//    中。第4个元素是图片的类型。PHP可以检测出将近18种不同文件 类型的大小，包括 PNG、JPEG、GIF、SWF (Flash 文件)、TIFF、BMP 和 PSD (Photoshop)。
//    通过image_type_to_mime_type ()函数，你可以转变数组中的类型为一个合法的mime类型， 例如
//    image/png 或者 application/xshockwave-flasho
//echo image_type_to_mime_type(1);

imagecopyresampled(
    $img, $bg, 0, 0, 0, 0, $size_x, $size_y, $size[0], $size[1]
);
//imagecopyresized()
//我们从读取的文件中复制PNG到目标图片去一我们的图表。这个函数需要传递10个参 数。前两个参数是目标图片的句柄和加载的PNG图片的句柄，后面是4组坐标：
//目标图片的左 上坐标，源图片的左上坐标，目标图片的右下坐标和源图片的右下坐标。你可以通过使用源图
//片合适的坐标复制源图片的一个部分到目标图片中。函数imagecopyresizedO也能复制图片并 且速度比较快，但是效果不是那么好，因为算法的功能差一些。

//图区域
$background = imagecolorallocatealpha($img, 127, 127, 192, 32);
//function imagefilledrectangle ($image, $x1, $y1, $x2, $y2, $color) {}
imagefilledrectangle($img, 20, 20, $size_x - 20, $size_y, $background);
imagefilledrectangle($img, 20, $size_y - 60, $size_x - 20, $size_y, $background);
//我们在背景图片上绘制两个蓝色区域：一个用作图表而另一个用作标题。因为我们想要区 域是透明的，所以创建一个alpha值
//是32的颜色。alpha值必须从0到127之间取值，其中0表 示完全不透明的颜色而127表示完全透明。

/* 值 */
$barcolor = imagecolorallocatealpha($img, 0, 0, 128, 80);
$spacing = ($size_x - 140) / count($values);
$start_x = 120;
foreach ($values as $key => $value) {
    $xl = $start_x + 0.2 * $spacing;
    $x2 = $start_x + 0.8 * $spacing;
    $yl = $size_y - 120;
    $y2 = $yl - (($value / $max_value) * ($size_y - 160));
    imagefilledrectangle($img, $xl, $yl, $x2, $y2, $barcolor);
    $start_x += $spacing;
}
//我们用imagef illedrectangle ()绘制柱形(使用在脚本开始的时候定义的$values数组)。 通过用可用的宽度除以数组中值的个数来计算柱形之间的间隔(
//    图片的宽度减去外面的边缘， 也就是左边140-120和右边
//的20的总数)。循环通过正确的数值增加$start_x组件而柱形的高 度从水平空间的百分之二十到百分之八十。在垂直方向，我们参考可绘制的最大值并据此调整 高度。

/*格子*/
$black = imagecolorallocate($img, 0, 0, 0);
$grey = imagecolorallocate($img, 128, 128, 192);
for ($i = $units; $i <= $max_value; $i += $units) {
    $xl = 110;
    $yl = $size_y - 120 - (($i / $max_value) * ($size_y - 160));
    $x2 = $size_x - 20;
    $y2 = $yl;
    imageline($img, $xl, $yl, $x2, $y2, ($i % (2 * $units)) == 0 ? $black : $grey);
}
/* 轴 */
imageline($img, 120, $size_y - 120, 120, 40, $black);
imageline($img, 120, $size_y - 120, $size_x - 20, $size_y - 120, $black);
//格子和轴用相同的方法绘制。唯一值得一提的事情是，我们在每一个黑色线条的后面绘制 灰色的线条，反之亦然。

/*标题*/
$c_x = $size_x / 2;
$c_y = $size_y - 40;
$box = imagettfbbox(20, 0, __DIR__ . '\arial.ttf', $title);
$sx = $box[4] - $box[0];
$sy = $box[5] + $box[1];
imagettftext($img, 20, 0, $c_x - $sx / 2, $c_y - ($sy / 2), $black, __DIR__ . '\arial.ttf', $title);
//我们想在底部的蓝色条状图里精确地居中绘制标题。因此，需要计算我们的文本需要的精 确的宽度(边框)。使用imagettfbbox()
//来实现这个操作。传递的参数分别是fontsize、angle、 fontfile和text。这些参数需要与我们随后绘制的文本保持一致。函数返回的数组包括8个 元素，
//两个参数分为一组，用来提供边框的4个角落的坐标。这些组的参数表示左下角、右下 角、右上角和左上角。在图9.9中，你可以看到根据文本wimages?w绘制的边框。


//绘制的基线（X）和轴（y）都是相对边框坐标的0线。就像你能看到的，左边实际上 并不是0。而且正常的字母的底部都是靠在基线上的，
//不过“尾画”是在基线下面。为了计算绘 制的文本的宽度，我们从元素4 （右上的x）减去元素0 （坐下的x）;为了计算高度，我们把元 素1
//（左下的y）加上元素5 （右上y）。然后可以把结果值用来调整文本在图片的居中处理上。
//计算边框的大小只能在文字的角度为0、90、180和270时有效。GD库通常不能完全准确地计 算边框的大小，但是这个问题在刚才提交的文字朝向中不存在。
$c_x = 50;
$c_y = ($size_y - 60) / 2;
$box = imagettfbbox(14, 90, __DIR__ . '\arial.ttf', $title2);
$sx = $box[4] - $box[0];
$sy = $box[5] + $box[1];
imagettftext($img, 14, 90, $c_x - ($sx / 2), $c_y - ($sy / 2), $black, __DIR__ . '\arial.ttf', $title2);

//我们对Y轴上的标题做同样的处理，不过我们使用的角度为90度。其他的代码不变。


/*标签*/
$c_y = $size_y - 100;
$start_x = 120;
foreach ($values as $label => $dummy) {
    $box = imagettfbbox(12, 0, __DIR__ . '\arial.ttf', $label);
    $sx = $box[4] - $box[0];
    $sy = $box[5] + $box[1];

    $c_x = $start_x + (0.5 * $spacing);
    imagettftext($img, 12, 0, $c_x - ($sx / 2), $c_y - ($sy / 2), $black,
        __DIR__ . '\arial.ttf', $label);
    $start_x += $spacing;
}
$r_x = 100;
for ($i = 0; $i <= $max_value; $i += ($units * 2)) {
    $c_y = $size_y - 120 - (($i / $max_value) * ($size_y - 160));
    $box = imagettfbbox(12, 0, __DIR__ . '\arial.ttf', $i / 100);
    $sx = $box[4] - $box[0];
    $sy = $box[5] + $box[1];
imagettftext($img ,12, 0, $r_x - $sx, $c_y- ($sy / 2), $black, __DIR__ . '\arial.ttf', $i / 100);
}
//在刚才的代码中，绘制不同的标签。X轴上的坐标处理不太有趣，但是对于Y轴上的，我 们尝试把文本对齐到右边的空白边距上，
//    而且不需要通过把绘制的文本的宽度除以2。
header('Content-type:image/png');
//header('Content - Length: ' . filesize($img));
imagepng($img);
